package com.dyava.commons.net;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.SystemUtils;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class NetUtils {
	/**
	 * 尝试连接 tcp 端口
	 * 
	 * @param addr
	 * @param port
	 * @param millsecTimeout
	 * @return 延时毫秒 -1为不通
	 */
	public static long ping(String addr, int port, int millsecTimeout) {
		Socket server = null;
		try {
			InetAddress address = InetAddress.getByName(addr);
			String ip = address.getHostAddress();
			server = new Socket();
			InetSocketAddress ipaddress = new InetSocketAddress(ip, port);
			long start = System.currentTimeMillis();
			server.connect(ipaddress, millsecTimeout);
			long end = System.currentTimeMillis();
			return (end - start);
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		} finally {
			IOUtils.closeQuietly(server);
		}
	}


	/**
	 * 尝试ping icmp
	 * 
	 * @param ipAddress
	 * @param timeOut
	 * @return 延时毫秒 -1为不通
	 */
	public static long ping(String ipAddress) {
		BufferedReader in = null;
		Runtime r = Runtime.getRuntime();
		String pingCommand = null;
		if (SystemUtils.IS_OS_WINDOWS) {
			pingCommand = "ping " + ipAddress + " -n 5";
		} else {
			pingCommand = "ping " + ipAddress + " -c 5";
		}
		Process p = null;
		try {// 执行命令并获取输出
//			System.out.println(pingCommand);
			p = r.exec(pingCommand);
			if (p == null) {
				return -1;
			}
			in = new BufferedReader(new InputStreamReader(p.getInputStream()));
			int userTime = -1;
			String line = null;
			while ((line = in.readLine()) != null) {
				int _userTime = getCheckResult(line);
				if (_userTime != -1 && (userTime == -1 || _userTime < userTime)) {
					userTime = _userTime;
					break;
				}
			} // 如果出现类似=20ms TTL=22这样的字符，出现的次数=测试次数 则返回真
			return userTime;
		} catch (Exception e) {
			e.printStackTrace();// 出现异常则返回假
			return -1;
		} finally {
			IOUtils.closeQuietly(in);
		}
	}

	private static int getCheckResult(String line) {
		// 若line含有=18ms TTL=16字样,说明已经ping通,返回1,否則返回0
		Pattern pattern = Pattern.compile("(\\d+)ms\\s+TTL=\\d+", Pattern.CASE_INSENSITIVE);
		Matcher matcher = pattern.matcher(line);
		while (matcher.find()) {
			String res = matcher.group(1);
			return Integer.parseInt(res);
		}
		return -1;
	}

}
